using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reflection;
using System.ServiceModel;
using Facebook.Core.Contracts;
using Facebook.Core.Responses;
using Facebook.Core.ServiceContracts;

namespace Facebook.Core.Services
{
    public class FacebookService : IFacebookService, IApiCaller
    {
        #region IApiCaller Members

        public string GeneratedSignature { get; set; }
        public long GeneratedTicks { get; set; }
        public string ApiKey { get; set; }
        public string SessionKey { get; set; }

        #endregion

        #region IFacebookService Members

        [ApiCall(Method = FacebookURITemplates.Auth.createToken, HasSession = false)]
        public virtual auth_createToken_response_wrapper createToken()
        {
            var facebookStatusProxy = new ChannelFactory<IFacebookAuth>("FacebookAuthService");
            facebookStatusProxy.Endpoint.Behaviors.Add(new HookServiceBehaviour());

            IFacebookAuth facebookAuth = facebookStatusProxy.CreateChannel();
            auth_createToken_response_wrapper token = facebookAuth.createToken(
                ApiKey, 
                GeneratedSignature
                );

            ((IDisposable)facebookStatusProxy).Dispose();
            return token;
        }

        [ApiCall(Method = FacebookURITemplates.Auth.getSession, HasSession = false)]
        public virtual auth_getSession_response getSession(string auth_token)
        {
            var facebookStatusProxy = new ChannelFactory<IFacebookAuth>("FacebookAuthService");
            facebookStatusProxy.Endpoint.Behaviors.Add(new HookServiceBehaviour());

            IFacebookAuth facebookAuth = facebookStatusProxy.CreateChannel();
            auth_getSession_response session = facebookAuth.getSession(
                ApiKey, 
                GeneratedSignature,
                auth_token
                );

            ((IDisposable)facebookStatusProxy).Dispose();
            return session;
        }

        [ApiCall(Method = FacebookURITemplates.Status.setStatus)]
        public virtual void SetStatus(string status)
        {
            var facebookStatusProxy = new ChannelFactory<IFacebookStatus>("FacebookStatusService");
            facebookStatusProxy.Endpoint.Behaviors.Add(new HookServiceBehaviour());

            IFacebookStatus facebookStatus = facebookStatusProxy.CreateChannel();
            facebookStatus.setStatus(
                ApiKey,
                GeneratedSignature,
                GeneratedTicks,
                SessionKey,
                status);
            ((IDisposable) facebookStatusProxy).Dispose();
        }

        [ApiCall(Method = FacebookURITemplates.Fql.query)]
        public virtual Collection<T> FQLQuery<T>(string query)
        {

            Debug.WriteLine("<== Executing Query ==>");
            Debug.WriteLine(String.Empty);
            Debug.WriteLine(query);
            Debug.WriteLine(String.Empty);
            Debug.WriteLine("<== End Query ==>");

            var facebookFQLProxy = new ChannelFactory<IFacebookFQL>("FacebookFQLService");
            facebookFQLProxy.Endpoint.Behaviors.Add(new HookServiceBehaviour());

            IFacebookFQL facebookStatus = facebookFQLProxy.CreateChannel();

            fql_query_response<T> fromStatus = null;
//            facebookFQLType.GetMethods()[0].ReturnType == typeof(fql_query_response<status>)

            Type facebookFQLType = typeof(IFacebookFQL);
            MethodInfo[] methods = facebookFQLType.GetMethods();
            foreach (MethodInfo info in methods)
            {
                if (info.ReturnType == typeof (fql_query_response<T>))
                {
                    return info.Invoke(facebookStatus, new object[]
                                                    {
                                                        ApiKey,
                                                        GeneratedSignature,
                                                        GeneratedTicks,
                                                        SessionKey,
                                                        query
                                                    }) as fql_query_response<T>;
                }
            }


//            if (typeof (T) == typeof (status))
//            {
//                fromStatus = facebookStatus.queryFromStatus(
//                                 ApiKey,
//                                 GeneratedSignature,
//                                 GeneratedTicks,
//                                 SessionKey,
//                                 query
//                                 ) as fql_query_response<T>;
//            }
//            else if (typeof (T) == typeof (user))
//            {
//                fromStatus = facebookStatus.queryFromUser(
//                                 ApiKey,
//                                 GeneratedSignature,
//                                 GeneratedTicks,
//                                 SessionKey,
//                                 query
//                                 ) as fql_query_response<T>;
//            }

            ((IDisposable)facebookFQLProxy).Dispose();
            return fromStatus;
        }

        #endregion
    }
}